home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / digdug.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  7KB  |  316 lines

  1. /***************************************************************************
  2.  
  3.   machine.c
  4.  
  5.   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
  6.   I/O ports)
  7.  
  8. ***************************************************************************/
  9.  
  10. #include "driver.h"
  11. #include "vidhrdw/generic.h"
  12. #include "cpu/z80/z80.h"
  13.  
  14.  
  15. unsigned char *digdug_sharedram;
  16. static unsigned char interrupt_enable_1,interrupt_enable_2,interrupt_enable_3;
  17.  
  18. static int credits;
  19.  
  20. static void *nmi_timer;
  21.  
  22. WRITE_HANDLER( digdug_halt_w );
  23.  
  24.  
  25. void digdig_init_machine(void)
  26. {
  27.     credits = 0;
  28.     nmi_timer = 0;
  29.     interrupt_enable_1 = interrupt_enable_2 = interrupt_enable_3 = 0;
  30.     digdug_halt_w (0, 0);
  31. }
  32.  
  33.  
  34. READ_HANDLER( digdug_sharedram_r )
  35. {
  36.     return digdug_sharedram[offset];
  37. }
  38.  
  39.  
  40. WRITE_HANDLER( digdug_sharedram_w )
  41. {
  42.     /* a video ram write */
  43.     if (offset < 0x400)
  44.         dirtybuffer[offset] = 1;
  45.  
  46.     /* location 9b3d is set to zero just before CPU 2 spins */
  47.     if (offset == 0x1b3d && data == 0 && cpu_get_pc () == 0x1df1 && cpu_getactivecpu () == 1)
  48.         cpu_spinuntil_int ();
  49.  
  50.     digdug_sharedram[offset] = data;
  51. }
  52.  
  53.  
  54. /***************************************************************************
  55.  
  56.  Emulate the custom IO chip.
  57.  
  58. ***************************************************************************/
  59. static int customio_command;
  60. static int leftcoinpercred,leftcredpercoin;
  61. static int rightcoinpercred,rightcredpercoin;
  62. static unsigned char customio[16];
  63. static int mode;
  64.  
  65. WRITE_HANDLER( digdug_customio_data_w )
  66. {
  67.     customio[offset] = data;
  68.  
  69. logerror("%04x: custom IO offset %02x data %02x\n",cpu_get_pc(),offset,data);
  70.  
  71.     switch (customio_command)
  72.     {
  73.         case 0xc1:
  74.             if (offset == 8)
  75.             {
  76.                 leftcoinpercred = customio[2] & 0x0f;
  77.                 leftcredpercoin = customio[3] & 0x0f;
  78.                 rightcoinpercred = customio[4] & 0x0f;
  79.                 rightcredpercoin = customio[5] & 0x0f;
  80.             }
  81.             break;
  82.     }
  83. }
  84.  
  85.  
  86. READ_HANDLER( digdug_customio_data_r )
  87. {
  88.     switch (customio_command)
  89.     {
  90.         case 0x71:
  91.             if (offset == 0)
  92.             {
  93.                 if (mode)    /* switch mode */
  94.                 {
  95.                     /* bit 7 is the service switch */
  96.                                         return readinputport(4);
  97.                 }
  98.                 else    /* credits mode: return number of credits in BCD format */
  99.                 {
  100.                     int in;
  101.                     static int leftcoininserted;
  102.                     static int rightcoininserted;
  103.  
  104.  
  105.                                         in = readinputport(4);
  106.  
  107.                     /* check if the user inserted a coin */
  108.                     if (leftcoinpercred > 0)
  109.                     {
  110.                         if ((in & 0x01) == 0 && credits < 99)
  111.                         {
  112.                             leftcoininserted++;
  113.                             if (leftcoininserted >= leftcoinpercred)
  114.                             {
  115.                                 credits += leftcredpercoin;
  116.                                 leftcoininserted = 0;
  117.                             }
  118.                         }
  119.                         if ((in & 0x02) == 0 && credits < 99)
  120.                         {
  121.                             rightcoininserted++;
  122.                             if (rightcoininserted >= rightcoinpercred)
  123.                             {
  124.                                 credits += rightcredpercoin;
  125.                                 rightcoininserted = 0;
  126.                             }
  127.                         }
  128.                     }
  129.                     else credits = 2;
  130.  
  131.  
  132.                     /* check for 1 player start button */
  133.                     if ((in & 0x10) == 0)
  134.                         if (credits >= 1) credits--;
  135.  
  136.                     /* check for 2 players start button */
  137.                     if ((in & 0x20) == 0)
  138.                         if (credits >= 2) credits -= 2;
  139.  
  140.                     return (credits / 10) * 16 + credits % 10;
  141.                 }
  142.             }
  143.             else if (offset == 1)
  144.             {
  145.                 int p2 = readinputport (2);
  146.  
  147.                 if (mode == 0)
  148.                 {
  149.                     /* check directions, according to the following 8-position rule */
  150.                     /*         0          */
  151.                     /*        7 1         */
  152.                     /*       6 8 2        */
  153.                     /*        5 3         */
  154.                     /*         4          */
  155.                     if ((p2 & 0x01) == 0)        /* up */
  156.                         p2 = (p2 & ~0x0f) | 0x00;
  157.                     else if ((p2 & 0x02) == 0)    /* right */
  158.                         p2 = (p2 & ~0x0f) | 0x02;
  159.                     else if ((p2 & 0x04) == 0)    /* down */
  160.                         p2 = (p2 & ~0x0f) | 0x04;
  161.                     else if ((p2 & 0x08) == 0) /* left */
  162.                         p2 = (p2 & ~0x0f) | 0x06;
  163.                     else
  164.                         p2 = (p2 & ~0x0f) | 0x08;
  165.                 }
  166.  
  167.                 return p2;
  168.             }
  169.                         else if (offset == 2)
  170.             {
  171.                                 int p2 = readinputport (3);
  172.  
  173.                 if (mode == 0)
  174.                 {
  175.                     /* check directions, according to the following 8-position rule */
  176.                     /*         0          */
  177.                     /*        7 1         */
  178.                     /*       6 8 2        */
  179.                     /*        5 3         */
  180.                     /*         4          */
  181.                     if ((p2 & 0x01) == 0)        /* up */
  182.                         p2 = (p2 & ~0x0f) | 0x00;
  183.                     else if ((p2 & 0x02) == 0)    /* right */
  184.                         p2 = (p2 & ~0x0f) | 0x02;
  185.                     else if ((p2 & 0x04) == 0)    /* down */
  186.                         p2 = (p2 & ~0x0f) | 0x04;
  187.                     else if ((p2 & 0x08) == 0) /* left */
  188.                         p2 = (p2 & ~0x0f) | 0x06;
  189.                     else
  190.                         p2 = (p2 & ~0x0f) | 0x08;
  191.                 }
  192.  
  193.                                 return p2; /*p2 jochen*/
  194.             }
  195.             break;
  196.  
  197.         case 0xb1:    /* status? */
  198.             if (offset <= 2)
  199.                 return 0;
  200.             break;
  201.  
  202.         case 0xd2:    /* checking the dipswitches */
  203.             if (offset == 0)
  204.                 return readinputport (0);
  205.             else if (offset == 1)
  206.                 return readinputport (1);
  207.             break;
  208.     }
  209.  
  210.     return -1;
  211. }
  212.  
  213.  
  214. READ_HANDLER( digdug_customio_r )
  215. {
  216.     return customio_command;
  217. }
  218.  
  219. void digdug_nmi_generate (int param)
  220. {
  221.     cpu_cause_interrupt (0, Z80_NMI_INT);
  222. }
  223.  
  224.  
  225. WRITE_HANDLER( digdug_customio_w )
  226. {
  227.     if (data != 0x10 && data != 0x71)
  228.         logerror("%04x: custom IO command %02x\n",cpu_get_pc(),data);
  229.  
  230.     customio_command = data;
  231.  
  232.     switch (data)
  233.     {
  234.         case 0x10:
  235.             if (nmi_timer) timer_remove (nmi_timer);
  236.             nmi_timer = 0;
  237.             return;
  238.  
  239.         case 0xa1:    /* go into switch mode */
  240.             mode = 1;
  241.             break;
  242.  
  243.         case 0xc1:
  244.         case 0xe1:    /* go into credit mode */
  245.             mode = 0;
  246.             break;
  247.  
  248.         case 0xb1:    /* status? */
  249.             credits = 0;    /* this is a good time to reset the credits counter */
  250.             break;
  251.     }
  252.  
  253.     nmi_timer = timer_pulse (TIME_IN_USEC (50), 0, digdug_nmi_generate);
  254. }
  255.  
  256.  
  257.  
  258. WRITE_HANDLER( digdug_halt_w )
  259. {
  260.     if (data & 1)
  261.     {
  262.         cpu_set_reset_line(1,CLEAR_LINE);
  263.         cpu_set_reset_line(2,CLEAR_LINE);
  264.     }
  265.     else
  266.     {
  267.         cpu_set_reset_line(1,ASSERT_LINE);
  268.         cpu_set_reset_line(2,ASSERT_LINE);
  269.     }
  270. }
  271.  
  272.  
  273.  
  274. WRITE_HANDLER( digdug_interrupt_enable_1_w )
  275. {
  276.     interrupt_enable_1 = (data&1);
  277. }
  278.  
  279.  
  280.  
  281. int digdug_interrupt_1(void)
  282. {
  283.     if (interrupt_enable_1) return interrupt();
  284.     else return ignore_interrupt();
  285. }
  286.  
  287.  
  288.  
  289. WRITE_HANDLER( digdug_interrupt_enable_2_w )
  290. {
  291.     interrupt_enable_2 = data & 1;
  292. }
  293.  
  294.  
  295.  
  296. int digdug_interrupt_2(void)
  297. {
  298.     if (interrupt_enable_2) return interrupt();
  299.     else return ignore_interrupt();
  300. }
  301.  
  302.  
  303.  
  304. WRITE_HANDLER( digdug_interrupt_enable_3_w )
  305. {
  306.     interrupt_enable_3 = !(data & 1);
  307. }
  308.  
  309.  
  310.  
  311. int digdug_interrupt_3(void)
  312. {
  313.     if (interrupt_enable_3) return nmi_interrupt();
  314.     else return ignore_interrupt();
  315. }
  316.